Skip to content

feat(task): add persistent task queue with Durable Object executor - #196

Open
PIKACHUIM wants to merge 2 commits into
mainfrom
feat/task-system
Open

PIKACHUIM wants to merge 2 commits into
mainfrom
feat/task-system

Conversation

@PIKACHUIM

Copy link
Copy Markdown
Member

Summary / 摘要

把 /api/task/* 从占位实现换成真正的持久化任务队列,并把长耗时文件操作从请求内移到后台执行。

用户可感知的变化

  • 复制 / 移动超过阈值(task_sync_threshold_mb,默认 32MB)时改为后台任务,接口立即返回 data.tasks;小操作仍在请求内完成,并同样出现在「已完成」任务列表。
  • 前端任务页现在可以看到真实的进度、状态、错误,并支持取消 / 重试 / 删除 / 批量清理(字段名与 state 数值和 Go 版完全一致)。
  • URL 离线下载(POST /api/fs/add_offline_download)从固定的 501 变成可用功能;默认关闭,需显式配置主机白名单。
  • 跨存储复制此前会把目标物理路径交给源驱动,实际行为是错的;现在由共享传输引擎真正完成跨存储传输。

实现要点

  • 新增 TaskRunner Durable Object:任务存内置 SQLite(按行更新)、alarm 自驱执行、入队即开跑;僵尸任务自动回收,连续无进展熔断。
  • 没有 DO 绑定的运行时(EdgeOne / ESA / Vercel / Node)自动降级为「每类型一份 JSON 文档 + 租约」,由 cron 或 POST /api/task/run 驱动。
  • 新增共享传输引擎 internal/op/transfer.ts:rapidUpload → putUrl(服务端直传)→ 可续传分片 → putStream → 限内存缓冲;分片会话写入 cursor,大文件中途被打断可续传。
  • 单次 tick 预算可配置(task_tick_budget_ms,0=自动,200–60000ms);默认 2000ms,按免费计划保守取值。
  • 任务置为 succeeded 前强制校验(目标存在性、文件数、move 源已删除),校验失败直接判失败并给出差集。
  • 新增设置项(设置页「流量」分组)与文档;wrangler.jsonc 增加 TASK_DO 绑定、v2 migration 与每分钟 cron。

配置 / 兼容性变化

  • /fs/copy、/fs/move 在大操作下改为异步并返回 data.tasks(对齐 Go 的 FsCopy/FsMove);小操作响应不变。

  • /fs/add_offline_download 不再是 501;未配置 ALLOW_OFFLINE_DOWNLOAD 时返回 403。

  • 新增环境变量:ALLOW_OFFLINE_DOWNLOAD、PUBLIC_ORIGIN(后台解析相对下载直链用)。

  • 部署会新增一个 TaskRunner DO 命名空间(免费计划支持 SQLite DO),migration tag v2。

  • This PR has breaking changes.
    / 此 PR 包含破坏性变更。

  • This PR changes public API, config, storage format, or migration behavior.
    / 此 PR 修改了公开 API、配置、存储格式或迁移行为。

  • This PR requires corresponding changes in related repositories.
    / 此 PR 需要关联仓库同步修改。

Related repository PRs / 关联仓库 PR:

  • OpenList:
  • OpenList-Docs:

Related Issues / 关联 Issue

Relates to #___

Testing / 测试

  • npx tsc -p tsconfig.json --noEmit(类型检查通过)
  • npx tsx --test "src/backend/internal/task/*.test.ts"(19 项通过)
  • npx tsx --test src/backend/internal/task/handlers/offline_download.test.ts(7 项通过)
  • npx tsx --test src/backend/server/task_api.test.ts(10 项通过)
  • npx tsx --test "src/backend/server/*.test.ts"(244 项,243 通过)
  • npm run test:model(39 项通过)
  • npm run test:pkg(33 项通过)
  • npx tsx scripts/test-task-api.mts(冒烟通过)
  • npx wrangler deploy --dry-run(打包通过,识别 TASK_DO 绑定)
  • Manual test / 手动测试:尚未在真实部署上跑大目录复制与断点续传

说明:server 套件中 storage_update_guangyapan.test.ts 失败,但在未改动的干净代码上同样失败
(已用 git stash 在原始 HEAD 上复现),与本次改动无关。

Checklist / 检查清单

  • I have read CONTRIBUTING.
    / 我已阅读 CONTRIBUTING。
  • I confirm this contribution follows the repository license, contribution policy, and code of conduct.
    / 我确认此贡献符合仓库许可证、贡献规范和行为准则。
  • I have formatted the changed code with prettier where applicable.
    / 我已按适用情况使用 prettier 格式化变更代码。
    说明:本机工作区为 CRLF,prettier --check 对仓库内既有文件同样报错(整文件行尾差异),
    为避免产生数千行无意义 diff 未执行 prettier --write;新文件已按仓库风格编写。
  • I have requested review from relevant maintainers or code owners where applicable.
    / 我已在适用情况下请求相关维护者或代码所有者审查。

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content.
    / 此 PR 包含 AI 辅助内容。

Tools used / 使用工具:

  • ChatGPT
  • Codex
  • GitHub Copilot
  • Claude
  • Gemini
  • Other (please specify) / 其他(请注明): CodeBuddy

Usage scope / 使用范围:

  • Code generation / 代码生成

  • Refactoring / 重构

  • Documentation / 文档

  • Tests / 测试

  • Translation / 翻译

  • Review assistance / 审查辅助

  • I have reviewed and validated all AI-assisted content included in this PR.
    / 我已审核并验证此 PR 中的所有 AI 辅助内容。

  • I have ensured that all AI-assisted commits include Co-Authored-By attribution.
    / 我已确保所有 AI 辅助提交都包含 Co-Authored-By 归属信息。

  • I can reproduce all AI-assisted content included in this PR without any AI tools.
    / 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。

Reviewer Notes / 审查要点

  • src/backend/internal/task/runner.ts:认领 / 断点 / 取消 / 退避 / 熔断 / 校验的唯一入口。
  • src/backend/durable-objects/TaskRunner.ts:SQLite claim 用单条 UPDATE ... RETURNING,避免并发重复执行。
  • src/backend/internal/op/transfer.ts:安全相关(逐跳 SSRF 校验、allowHosts)与续传逻辑。
  • src/backend/server/fs.ts:decideCopyMoveMode 决定同步/异步;注意顶层条目一条任务(与 Go 一致)。

pikachuren added 2 commits November 9, 2026 18:57
Replace the placeholder /api/task/* implementation with a real queue:

- TaskRunner Durable Object (SQLite + alarm) executes tasks and keeps them
  across invocations; auto-recovers zombie tasks and chains alarms until the
  queue is idle. Falls back to a per-type JSON document store when no DO
  binding exists (EdgeOne / ESA / Vercel / Node), driven by cron or
  POST /api/task/run.
- copy/move become background tasks above a configurable size threshold
  (task_sync_threshold_mb, default 32MB); small operations stay synchronous
  and are still recorded in the done list.
- Cross-storage copies previously handed the destination physical path to the
  source driver, which silently misbehaved. A shared transfer engine now
  supports rapidUpload -> putUrl -> resumable multipart -> putStream ->
  bounded buffer, with the multipart cursor persisted for resumability.
- URL offline download replaces the old 501. It is disabled unless
  ALLOW_OFFLINE_DOWNLOAD lists the target hosts; SSRF checks still apply.
- Tick budget defaults to a free-plan-safe 2s and is configurable per
  deployment (200-60000ms); parallel unit count is capped at 4.
- Tasks are verified before being marked succeeded (target existence, file
  counts, source removal for moves) and expose the same TaskInfo/state
  numbers as the Go backend.
- Add settings, docs, wrangler bindings (TASK_DO + v2 migration + cron) and
  tests for the store, runner, settings, API contract and download allowlist.
@PIKACHUIM PIKACHUIM linked an issue Nov 10, 2026 that may be closed by this pull request
3 of 4 tasks
@PIKACHUIM PIKACHUIM added the enhancement New feature or request label Nov 10, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
openlist-work 4b81819 Nov 10 2026, 10:04 AM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
openlist-tsworkers 4b81819 Nov 10 2026, 10:04 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] 离线下载报错

1 participant